// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: declaration of CImplContent.
//   $Id$


#pragma once

#include "impl.h"
#include "WaitWithMessageLoop.h"
#include <map>
struct IXPathExpression;
struct IXPathResult;
struct IXPathEvaluator;
enum EXPathResultType;


class CDOM3Document;

typedef std::map<CComBSTR,CComPtr<IXPathExpression> > CMapCComBSTRToXPathExpression;
typedef std::pair<CComBSTR,CComPtr<IXPathExpression> > CPairCComBSTRToXPathExpression;
typedef IXMLDOMNode CNode;
DWORD WINAPI ThreadGetContent(LPVOID vdArg);
class CEvaluator;
class CImplContent : public CImpl
{
	//To allow threading.
	friend DWORD WINAPI ThreadGetContent(LPVOID vdArg);
	//only due to poor initial planning, where ALL data was public
	friend class CImplModel;
	friend class CEvaluator;
public:
	virtual void notifyDelete();
	CImplContent(CImplModel* pModel);
	virtual ~CImplContent();

	HRESULT GetContent();
private:
	HRESULT getXPathResult(BSTR sXPath, CNode* pContextNode, EXPathResultType eType, IXPathResult ** pResult);
	//Object to give to external callers to permit XPath expressions to be evaluated on this content
	//	by objects in other dlls.
	CComObject<CEvaluator> * m_pEvaluatorProxy;
protected:
	//allows derived-clas specific processing of reset.  
	//	this does nothing, so possibly should be pure virtual.
	virtual void onReset();
	//Restrict direct access to these, the model should be the only 
	//	object able to get data.
	HRESULT getInstanceData(BSTR sXPath, CNode* pContextNode,  IXPathResult** ppData);
	HRESULT getInstanceNumber(BSTR sXPath,CNode* pContextNode, double* pdData);
	HRESULT getInstanceString(BSTR sXPath, CNode* pContextNode, BSTR* psData);
	
	HRESULT getInstanceNode(BSTR sXPath, CNode* pContextNode, CNode** ppNode);
	HRESULT getInstanceNodeList(BSTR sXPath, CNode* pContextNode, IXPathResult** ppResult);
	HRESULT putInstanceString(BSTR sXPath, CNode* pContextNode, BSTR sData);
	
	HRESULT putInstanceData(CNode* pRecipientNode,  IXPathResult * pData);
	HRESULT putInstanceString(CNode* pRecipientNode, BSTR sData);

public:
	virtual HRESULT oninsert() { return S_OK; };
	virtual HRESULT ondelete() { return S_OK; };

//	virtual HRESULT load(CDOM3Document* pDom);

	//XForms events

	virtual HRESULT reset();

private:
	CComPtr<IXMLDOMSchemaCollection> m_pSchemaCache;
	CMapCComBSTRToXPathExpression m_ExprMap;
	
public:
	void put_schemaCache(IXMLDOMSchemaCollection * pCache);

	CComBSTR m_sHref;

	//Where there is no inline or external document specified,
	//	if there is a schema, and a document element attribute
	//	(formsplayer specific) the schema will generate a document.
	CComBSTR m_sDocumentElement;
	
	bool getInstanceBoolean(IXMLDOMNode * pContextNode,BSTR sRef);
	CComPtr<IXMLDOMParseError> m_pLastError;

protected:
	CDOM3Document* m_pdomLive;
	CDOM3Document* m_pdomInitial;
	CImplModel* m_pModel;
	HANDLE m_hLoadEvent;
	HANDLE m_hLoadThread;

public:
	HRESULT GetEvaluator(IXPathEvaluator ** ppEvaluator);

	HRESULT getSchemaCache(IXMLDOMSchemaCollection ** pSchemaCache)
	{
		if(m_pSchemaCache) {
			*pSchemaCache = m_pSchemaCache;
			(*pSchemaCache)->AddRef();
		}
		return S_OK;
	}
	HRESULT getNewDocument(IXMLDOMDocument ** ppRetDoc);
	CDOM3Document * GetLiveDOM();
	bool m_bLoadSuccessful;
private:
	HRESULT GetContentNow();
};

